package com.lgt_enterprise_android.utils

import android.content.Context
import android.content.Intent
import android.util.Log
import android.widget.Toast
import com.alibaba.fastjson.JSONObject
import com.lgt_enterprise_android.BuildConfig
import com.lgt_enterprise_android.Constant
import com.lgt_enterprise_android.base.BaseActivity
import com.lgt_enterprise_android.base.MyApp
import com.lgt_enterprise_android.view.pages.LoginActivity
import com.util.AppUtil
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.io.IOException
import java.nio.charset.Charset
import java.security.cert.CertificateException
import java.security.cert.X509Certificate
import javax.net.ssl.HostnameVerifier
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager

class BasicHttpKt {
    companion object {

        var mOkHttpClient: OkHttpClient;

        init {
            val builder = getUnsafeOkHttpClient()
            builder.addInterceptor { chain ->
                val temp = "{'Version':'" + AppUtil.getVersionName(MyApp.getInstance()) + "','Platform':2,'OSVersion':" + android.os.Build.VERSION.SDK_INT + "}"

                val request = chain.request()
                        .newBuilder()
                        .addHeader("device-info", temp.replace("'", "\""))
                        .build()
                chain.proceed(request)
            }
            if (BuildConfig.DEBUG) {
                builder.addInterceptor(LoggingInterceptor())
            }

            mOkHttpClient = builder.build();
        }

        /**
         * 绕过验证
         * @return
         */
        fun getUnsafeOkHttpClient(): OkHttpClient.Builder {
            val trustAllCerts: Array<TrustManager> = arrayOf(object : X509TrustManager {
                @Throws(CertificateException::class)
                override fun checkClientTrusted(
                        chain: Array<java.security.cert.X509Certificate>, authType: String) {
                }

                @Throws(CertificateException::class)
                override fun checkServerTrusted(chain: Array<java.security.cert.X509Certificate>, authType: String) {
                }

                override fun getAcceptedIssuers(): Array<X509Certificate?> {
                    return arrayOfNulls(0)
                }
            })

            val sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, java.security.SecureRandom())

            val sslSocketFactory = sc.socketFactory
            val builder = OkHttpClient.Builder()
            builder.sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager)
            builder.hostnameVerifier(HostnameVerifier { _, _ -> true })

            return builder;
        }

        class LoggingInterceptor : Interceptor {
            @Throws(IOException::class)
            override fun intercept(chain: Interceptor.Chain): Response {
                //这个chain里面包含了request和response，所以你要什么都可以从这里拿
                val request = chain.request()

                val t1 = System.nanoTime()//请求发起的时间

                val requestBody = request.body
                var body: String? = null
                if (requestBody != null) {
                    val buffer = okio.Buffer()
                    requestBody.writeTo(buffer)
//                    val contentType = requestBody.contentType()
                    //                    if (contentType != null) {
                    //                        charset = contentType.charset(UTF8);
                    //                    }
                    body = buffer.readString(Charset.defaultCharset())
                }

                Log.d("HTTP", "**********************************发送请求: method：" + request.method + "#" + request.url + "#" + body)

                var response: Response? = null;

                try {
                    response = chain.proceed(request)
                } catch (ex: Exception) {
                    response = null
                }


                val t2 = System.nanoTime()//收到响应的时间

                //这里不能直接使用response.body().string()的方式输出日志
                //因为response.body().string()之后，response中的流会被关闭，程序会报错，我们需要创建出一
                //个新的response给应用层处理
                val responseBody = response?.peekBody((1024 * 1024).toLong())

                LogX.snipet("******HTTP_RESPONSE******", String.format("接收响应: [%s] %n返回json:【%s】 %.1fms%n",
                        response?.request?.url,
                        responseBody?.string(),
                        (t2 - t1) / 1e6))

                return response!!
            }
        }

        suspend fun getExec(context: Context, url: String): Any? {
            if (!AppUtil.isNetworkAvailable(context)) {
                if (context is BaseActivity) {
                    context.showToast("网络不给力，请稍后再试")
                }
                return null;
            }

            val request = Request.Builder().url(url).addHeader("Authorization", "Bearer " + Constant.token).build()
            var returnVal: Any? = null
            var response: Response? = null
            withContext(Dispatchers.IO) {
                try {
                    response = mOkHttpClient.newCall(request).execute();
                } catch (ex: java.lang.Exception) {
                    print(ex.stackTrace)
                }
            }

            response?.let {
                it.body?.let {
                    val jsonObject: JSONObject = JSONObject.parseObject(it.string())
                    val code = jsonObject.getIntValue("code");
                    if (code == 40003 || code == 40004) {
                        val intent = Intent(context, LoginActivity::class.java)
                        intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
                        intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK
                        PrefUtils.setSharedPrefStringData(context, PrefUtils.TOKEN, "")
                        context.startActivity(intent)
                    } else if (jsonObject.getIntValue("code") != 10000) {
                        Toast.makeText(context, jsonObject.getString("message"), Toast.LENGTH_SHORT).show();
                    } else {
                        returnVal = jsonObject.getJSONObject("data")
                    }
                }
            } ?: let {
                Toast.makeText(context, "网络错误，请稍后再试", Toast.LENGTH_SHORT).show()
            }

            return returnVal
        }
    }
}